{-# LANGUAGE OverloadedStrings #-}
module Pages.AddSubmissionDigestive where

import Pages.DigestiveHelpers(BlazeForm, tabularInput, tabularSection, tabularForm)
import State.Database(ProblemId(..), Program(..), Language(..))
import Control.Applicative((<$>), (<*>))
import Text.Digestive.Forms(FormInput)
import Text.Digestive.Validate(validate, checkM)
import Data.Maybe(fromMaybe)
import Text.Digestive.Blaze.Html5(inputRadio, inputTextArea, inputTextRead)

-- | A form for the solution submission
submissionForm :: (Monad m, Functor m, FormInput i f) => (ProblemId -> m Bool) -> BlazeForm m i (ProblemId, Program)
submissionForm problemChecker = tabularForm $
    (,) <$> (tabularInputProblemId problemChecker) <*> tabularInputProgram

-- | A formlet to input a program
inputProgram :: (Functor m, Monad m, FormInput i f) => Maybe Program -> BlazeForm m i Program
inputProgram initial =
    Program
    <$> tabularInputLanguage (fromMaybe Haskell $ programLanguage <$> initial)
    <*> tabularInputCode (programCode <$> initial)

-- | A formlet to input a program code
tabularInputCode initial = tabularInput "Code:" (inputTextArea (Just 20) (Just 40) initial)

-- | A formlet to input a program language
tabularInputLanguage initial = let languageChoice = [(Haskell, "Haskell"),(Cpp, "C++"),(Java, "Java"),(CSharp, "C#")]
                       in tabularInput "Language:" (inputRadio False initial languageChoice)

-- | A form to input a program
tabularInputProgram :: (Functor m, Monad m, FormInput i f) => BlazeForm m i Program
tabularInputProgram = tabularSection "Program:" (inputProgram Nothing)


tabularInputProblemId :: (Monad m, Functor m, FormInput i f) => (ProblemId -> m Bool) -> BlazeForm m i ProblemId
tabularInputProblemId checker = tabularInput "Problem Id:" (ProblemId <$> inputTextRead "Cannot parse an integer" Nothing)
                   `validate` checkM  "The problem specified does not exist" checker
